package ch6;

import util.ReadOnlyIterator;

import java.util.*;

/**
 * 减少不可变对象占用的空间
 * 通过在BigImutaableObject.createRegistry方法所创建的HashMap实例是老的BigImutableObject实例
 * 的registry变量的一个浅复制对象，造成这两个HashMap实例会共用大量的存储空间（主要是堆中的BigObject）
 */

public final class BigImutableObject implements Iterable<Map.Entry<String, BigImutableObject.BigObject>> {

    private final HashMap<String, BigObject> registry;

    public BigImutableObject(HashMap<String, BigObject> registry) {
        this.registry = registry;
    }

    public BigImutableObject(BigImutableObject prototype, String key, BigObject newValue) {
        this(createRegistry(prototype, key, newValue));
    }

    @SuppressWarnings("unchecked")
    private static HashMap<String, BigObject> createRegistry(
            BigImutableObject prototype,
            String key,
            BigObject newValue) {
        // 从现有对象中 浅复制 字段
        HashMap<String, BigObject> newRegistry = (HashMap<String, BigObject>) prototype.registry.clone();
        // 仅更新需要更新的部分
        newRegistry.put(key, newValue);
        return newRegistry;
    }

    @Override
    public Iterator<Map.Entry<String, BigObject>> iterator() {
        // 对entrySet进行防御性复制
        final Set<Map.Entry<String, BigObject>> readOnlyEntries = Collections.unmodifiableSet(registry.entrySet());

        // 返回一个只读的Iterator实例
        return ReadOnlyIterator.with(readOnlyEntries.iterator());
    }


    public BigObject getObject(String key) {
        return registry.get(key);
    }

    class BigObject {
        // ...
    }
}
